<template>
    <n-data-table ref="dataTableRef" remote :columns="curColumns" :data="curData" :pagination="pagination&&paginationConf" :loading="loading"
        :row-key="(row) => row[curConf.idKey]" :checked-row-keys="curSelectId" @update:checked-row-keys="handleCheck"
        @update:filters="handleUpdateFilter" v-bind="$attrs"  ></n-data-table>
</template>

<script lang="ts" setup>
import { computed, PropType, reactive, ref, h, nextTick } from 'vue'
import { IBaseTableConfig, IBaseTableData, ColumnsConfig } from './type'
import { beforeColumns } from "./util"
import { filterControlsMap, getFilterControl} from "./filterControls"
import { FilterIcon } from "naive-ui/es/_internal/icons/index.mjs"
import { NBaseIcon } from "naive-ui/es/_internal/index.mjs";

const props = defineProps({
    data: {
        type: Array,
        default: () => []
    },
    columns: {
        type: Array as PropType<ColumnsConfig[]>,
        default: () => []
    },
    pagination: {
        type: Boolean,
        default: true
    },
    config: {
        type: Object as PropType<IBaseTableConfig>,
        default: () => ({})
    }

})
const defConf = {
    page: 1,
    size: 10,
    pageKey: 'page',
    sizeKey: 'size',
    pageSizes: [10, 20, 30, 40, 50, 100],
    fixQuery: {

    },
    idKey: 'id'
}
const dataTableRef = ref()
const loading = ref(false)
// 以id为准
const curSelectId = ref([])
// 如果是异步的 初始选中 如果数据没有加载 则不会有数据 仅当前选中辅助使用
const curSelectItems = ref([])
// 请求出去的参数
let query = {}
// 过滤的参数
let filterQuery:any =ref({})

const emits = defineEmits(['update:data','onFilter'])

const curConf = computed(() => {
    return Object.assign({}, defConf, props.config)
})

const getSourceData = () => {
    return JSON.parse(JSON.stringify(props.data || []))
}
const curData = ref(getSourceData())
// 分页配置
const paginationConf = reactive({
    page: curConf.value.page,
    pageSize: curConf.value.size,
    showSizePicker: true,
    pageSizes: curConf.value.pageSizes,
    itemCount: 0,
    pageCount: 0,
    prefix({ itemCount }) {
        return `共 ${itemCount} 条`
    },
    onChange: (page: number) => {
        paginationConf.page = page

        isApi() && getData({
            [curConf.value.pageKey]: page,
        })
    },
    onUpdatePageSize: (pageSize: number) => {
        paginationConf.pageSize = pageSize
        paginationConf.page = curConf.value.page

        isApi() && getData({
            [curConf.value.pageKey]: curConf.value.page,
            [curConf.value.sizeKey]: pageSize
        })
    }
})

const columnsKeyArr = []
const filterColumnsKeyArr:string[] = []
// 处理cols
const curColumns = computed(() => {
    return props.columns.map((col: ColumnsConfig) => {
        if(!col.renderFilterMenu&&col.filterControl&&col.filterControlType&&filterControlsMap[col.filterControlType]){
            col.renderFilterMenu = (action)=>{
                console.log('renderFilterMenu',action)
                return getFilterControl(col,action,(value)=>{
                    filterQuery.value[col.key] = value
                    emits('onFilter',filterQuery.value,col)
                    onSearchOwn(filterQuery.value,true)
                })
            }
            if(!col.renderFilterIcon){
                col.renderFilterIcon = (opt)=>{
                    const  mergedClsPrefix ='n'
                    return h('div',
                        {
                            "data-data-table-filter": true,
                            class:[`${mergedClsPrefix}-data-table-filter`, {
                            [`${mergedClsPrefix}-data-table-filter--active`]:filterQuery.value[col.key],
                            [`${mergedClsPrefix}-data-table-filter--show`]: opt.show
                        }]
                        },
                        h(NBaseIcon, {
                            clsPrefix: mergedClsPrefix
                        }, {
                            default: () => h(FilterIcon, null)
                        })
                    )
                }
            }
            
        }
        beforeColumns(col)
        if(col.key !== 'actions'){
            columnsKeyArr.push(col.key)
            if(col.filterControl){
                if(col.filterControl.value){
                    filterQuery.value[col.key] = col.filterControl.value
                }
                filterColumnsKeyArr.push(col.key)
            }
        }
        return col
    })
})
// 判断是否异步
const isApi = () => {
    return curConf.value.apiFunc
}
// 勾选
const handleCheck = (select, selectObjArr, row) => {
    curSelectId.value = select
    curSelectItems.value = selectObjArr

}

// 重置分页
const resetPagination = () => {
    query = {}
    paginationConf.page = curConf.value.page
    paginationConf.pageSize = curConf.value.size
}

// 请求数据
const getData = (q={}) => {
    query = {
        [curConf.value.pageKey]: curConf.value.page,
        [curConf.value.sizeKey]: curConf.value.size,
        ...query,
        ...curConf.value.fixQuery,
        ...q
    }
    console.log('请求出去的参数',query)
    filterColumnsKeyArr.forEach((key)=>{
        if(q.hasOwnProperty(key)){
            filterQuery.value[key] = q[key]
        }
    })
    loading.value = true
    curConf.value.apiFunc(query).then((res: IBaseTableData<any>) => {
        let sourceData: any = res
        if (curConf.value.formatTableData) {
            sourceData = curConf.value.formatTableData(sourceData)
        }
        curData.value = sourceData.items
        paginationConf.pageCount = Math.ceil(res.page.total / curConf.value.size)
        paginationConf.itemCount = res.page.total

    }).finally(() => {
        loading.value = false
    })
}
const resetFilter = ()=>{
    filterQuery.value = {}
    props.columns.map((col)=>{
        if(col.filterControl){
            col.filterControl.value = null
        }
        if(col.filterOptionValue ){
            col.filterOptionValue  = ''
        }
        if(col.filterOptionValues&&col.filterOptionValues.length){
            col.filterOptionValues = []
        }
        return col
    })
    nextTick(() => {
        dataTableRef.value.clearFilters()
    })
    
}


const initData = () => {
    if (!isApi()) {
        curData.value = getSourceData()
        paginationConf.pageCount = Math.ceil(curData.value.length / paginationConf.pageSize)
        paginationConf.itemCount = curData.value.length
    }
}

const onSearchOwn = (q={}, isReset = true) => {
    isReset && resetPagination()
    if (isApi()) {
        getData(q)
    } else {
        if (isReset) {
            initData()

        } else {
            curData.value = curData.value.filter((item: any) => {
                return curConf.value.searchMap ? curConf.value.searchMap(q, item) : Object.keys(q).some(key => {
                    return String(item[key]).includes(q[key])
                })
            })
        }
        paginationConf.itemCount = curData.value.length
    }
}
const onSearch = (q={}, isReset = true,) => {
    onSearchOwn(q,isReset)
}

const onReset = () => {
    resetFilter()
    onSearchOwn({}, true)
}
const delUpdateData = () => {
    // 如果当前页 数据为一条并且不是第一页并且是最后一页 删除最后一条数据的时候page需要-1
    if (curData.value.length === 1 && paginationConf.page !== curConf.value.page && Math.floor(paginationConf.itemCount / paginationConf.pageSize) === paginationConf.page) {

        paginationConf.page--;
    }
    getData({
        [curConf.value.pageKey]: paginationConf.page
    })
}

const getSelect = () => {
    return {
        ids: curSelectId.value,
        items: curSelectItems.value
    }

}
const setSelect = (ids:any, items:any) => {
    curSelectId.value = ids || []
    curSelectItems.value = items || []
}

const handleUpdateFilter = (q:any,col: ColumnsConfig)=>{
    filterQuery.value = q
    emits('onFilter',filterQuery.value,col)
    onSearchOwn(filterQuery.value,true)
}

initData()
defineExpose({
    onSearch,
    onReset,
    delUpdateData,
    getSelect,
    setSelect
})
</script>
<style>
.filter-control-area{
    padding: 10px;
}
.filter-control-action{
    padding:8px 12px;
    text-align: center;
    border-top: 1px solid #ebeef5;
}
</style>